#include <iostream>
#include <assert.h>
#include <math.h>

bool
perform_trial(std::size_t total_voters, float spread_percentage, float error_percentage)
{
  std::size_t voteA = total_voters/2 + (std::size_t)ceil(total_voters*spread_percentage/2);
  std::size_t voteB = total_voters - voteA;
  //std::cout << "voteA = " << voteA << ", voteB = " << voteB << std::endl;
  assert (voteA > voteB);

  std::size_t recorded_voteA = 0;
  std::size_t recorded_voteB = 0;

  // Asssume that error_percentage is of the form 0.XXXX
  std::size_t bound = (std::size_t)ceil(error_percentage * 10000);
  std::size_t check = 0;

  for (std::size_t i = 0; i < voteA; ++i)
    {
      std::size_t prob = rand() % 10000;
      if (prob < bound)
	{
	  check++;
	  recorded_voteB++;
	}
      else
	{
	  recorded_voteA++;
	}
    }

  for (std::size_t i = 0; i < voteB; ++i)
    {
      std::size_t prob = rand() % 10000;
      if (prob < bound)
	{
	  check++;
	  recorded_voteA++;
	}
      else
	{
	  recorded_voteB++;
	}      
    }

  //std::cout << "check = " << check << ", % = " << 100*check/total_voters << std::endl;
  //std::cout << "recorded_voteA = " << recorded_voteA << ", recorded_voteB = " << recorded_voteB << std::endl;
  return (recorded_voteA > recorded_voteB);
}


void
get_input(std::size_t& total_voters, float& spread_percentage, float& error_percentage)
{
  std::cout << "Enter number of voters: ";
  std::cin >> total_voters;

  while (true)
    {
      std::cout << "Enter percentage spread between candidates (0.0 .. 1.0): ";
      std::cin >> spread_percentage;
      if ((spread_percentage > 0) && (spread_percentage < 1.0))
	{
	  break;
	}
    }

  while (true)
    {
      std::cout << "Enter voting error percentage (0.0 .. 1.0): ";
      std::cin >> error_percentage;
      if ((error_percentage > 0) && (error_percentage < 1.0))
	{
	  break;
	}
    }

}

int main()
{
  srand ( time(NULL) );
  
  std::size_t total_voters = 10000;
  float spread_percentage = 0.005;
  float error_percentage = 0.08;

  //get_input(total_voters, spread_percentage, error_percentage);

  std::size_t invalid_trials = 0;
  std::size_t total_trials = 10000;

  for (std::size_t i = 0; i < total_trials; ++i)
    {
      if (perform_trial(total_voters, spread_percentage, error_percentage) == false)
	{
	  invalid_trials++;
	}
    }

  float res = (100.0 * invalid_trials)/total_trials;

  std::cout << "Chance of an invalid election result after " << total_trials << " trials = " << res << "%" << std::endl;
}
